home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
hdutil.arc
/
MARK.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-08-25
|
14KB
|
346 lines
PAGE ,132
TITLE IBM-PC Mark/UnMark-Bad-Cluster Program, Version 2.20, 25-Aug-1986
;
; Written By Steven Georgiades
;
; IBM-PC/XT Mark/UnMark-Bad-Cluster Program
; This program will allow you to mark or unmark a cluster on your disk as
; bad. It should work under all versions of DOS 2.00 and higher, and should
; work on the PC, XT, AT, PCJr. and all compatibles. The programs is invoked
; as follows:
;
; MARK [d:] [/U | /M] n [[d:] [/U | /M] n [[...]]]
;
; d: Optional drive letter. If this is omitted, the default
; drive is used.
;
; /U Un-mark switch. The following clusters will be un-marked.
; If no switch is specified, Un-mark is assumed.
;
; /M Mark switch. The following clusters will be marked bad.
;
; n Cluster Number, in decimal. The first data cluster is 2.
; (Don't blame me. DOS defines it that way.)
;
;
; If you are using this program and find it of value, your
; contribution in any amount ($10.00 suggested) will be greatly
; appreciated. Makes checks payable to Steven M. Georgiades.
; Thank you.
;
; If you have any questions or comments about this or any other
; SMG program, write to me at the following address:
;
; Steven M. Georgiades
; 701-H South Hayward Street
; Anaheim, CA 92804
;
CODE SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
ORG 80H
PARAM LABEL BYTE
ORG 100H
MARK: JMP BEGIN
DIGIT DB "0123456789ABCDEF"
SIGNON DB "Mark, Version 2.20",13,10,10,"$"
CLSTMSG DB "Cluster XXXXX$"
INVALID DB " does not exist!",7,13,10,"$"
BADMSG DB " is already marked as bad",13,10,"$"
INUSEMSG DB " is currently in use by a file",13,10,"$"
RESVMSG DB " is reserved",13,10,"$"
NOTBAD DB " is not marked as bad",13,10,"$"
MARKMSG DB " has been marked as bad",13,10,"$"
UNMRKMSG DB " has been un-marked as bad",13,10,"$"
CLSTSEC DW ?
CLSTTOT DW ?
CLUST DW ?
DRIVE DB ?
EOF DW ?
FATSEC DW ?
FATSIZE DB ?
FLAG DB 0
OLDDRV DB -1
SECSIZE DW ?
BEGIN: MOV AH,9 ; Output Sign-On Message
MOV DX,OFFSET SIGNON
INT 21H
MOV AH,19H ; Get Default Drive Number
INT 21H
MOV DRIVE,AL ; and Save
MOV SI,OFFSET PARAM ; Set up Pointer to Parameter
LODSB ; Read Parameter Length
CBW
MOV BX,AX
MOV BYTE PTR [SI][BX],0 ; Terminate Parameter String
STRIP: LODSB ; Strip Off Leading Whitespace
CMP AL,' '
JE STRIP
CMP AL,9
JE STRIP
OR AL,AL ; If End-of-Parameter List,
JNZ NOTDONE
MOV AX,4C00H ; Exit to DOS
INT 21H
NOTDONE: CMP AL,'/' ; If Switch, Process
JNE NOSWITCH
LODSB ; Get Switch Letter
AND AL,0DFH ; Convert to Upper Case
CMP AL,'U' ; If '/U', Reset MARK Flag
JE SWITCHU
CMP AL,'M' ; If Not '/M', Next Character
JNE STRIP
MOV FLAG,-1 ; Else Set MARK Flag
JMP SHORT STRIP
SWITCHU: MOV FLAG,0 ; Reset MARK Flag
JMP SHORT STRIP
NOSWITCH: LODSB ; Get Drive Letter
CMP AL,':'
JNE NODRIVE
INC SI
AND AL,0DFH ; Convert to Upper Case
SUB AL,'A' ; Convert to Drive Number
MOV DRIVE,AL ; Save Drive Number
JMP STRIP ; Get Next Paramter
NODRIVE: SUB SI,2 ; ReUse Last Character
CALL GET_WORD ; Read Cluster Number (Hex)
MOV CLUST,DX ; Save Cluster Number
MOV AL,DRIVE ; If Different Drive,
CMP AL,OLDDRV
JE DRV_OK
PUSH SI ; Save Parameter Pointer
MOV OLDDRV,AL ; Save New Drive
MOV BX,OFFSET FATBUF ; Read Boot Record
MOV CX,1
MOV DX,0
INT 25H
POPF
MOV AX,FATBUF[11] ; Read Sector Size and Save
MOV SECSIZE,AX
MOV AL,BYTE PTR FATBUF[13] ; Read Sectors/Cluster and Save
XOR AH,AH
MOV CLSTSEC,AX
MOV BX,FATBUF[22] ; Read Sectors/FAT and Save
MOV FATSEC,BX
MOV AH,36H ; Get Total Data Clusters
MOV DL,DRIVE
INC DL
INT 21H
ADD DX,2
MOV CLSTTOT,DX ; and Save
MOV FATSIZE,3
MOV EOF,0FF8H
CMP DX,4081 ; If Necessary, Adjust FAT Size
JLE FAT_OK
MOV FATSIZE,4
MOV EOF,0FFF8H
FAT_OK: MOV AL,DRIVE ; Read FAT
MOV CX,FATSEC
MOV DX,1
MOV BX,OFFSET FATBUF
INT 25H
POPF
POP SI ; Restore Parameter Pointer
DRV_OK: MOV BX,CLUST ; Get Cluster Number
MOV AX,BX ; Convert Cluster No. to ASCII
MOV DI,OFFSET CLSTMSG[13]
CALL DEC5OUT
CALL STRIP0 ; Strip Off Leading Zeroes
MOV AH,9 ; Output Cluster Message
MOV DX,OFFSET CLSTMSG
INT 21H
CMP BX,CLSTTOT ; If Invalid, Say So
JAE CLST_BAD
CMP BX,2
JAE CLST_OK
CLST_BAD: MOV DX,OFFSET INVALID
JMP SHORT ERROUT
CLST_OK: CALL NEXTCLST ; Get Next Cluster Number
MOV AX,EOF ; Get EOF Value
CMP FLAG,0 ; If /U, Unmark
JE UNMARK
OR BX,BX ; Else Mark
JZ IS_FREE
CMP BX,AX ; If Reserved,
JB NOTINUSE
IN_USE: MOV DX,OFFSET INUSEMSG
JMP SHORT ERROUT ; Output Error Message
NOTINUSE: DEC AX
CMP BX,AX
JNE NOT_BAD
MOV DX,OFFSET BADMSG
JMP SHORT ERROUT
NOT_BAD: SUB AX,7
CMP BX,AX
JB IN_USE
MOV DX,OFFSET RESVMSG
JMP SHORT ERROUT
IS_FREE: MOV BX,CLUST ; Get Cluster Number
MOV AX,EOF ; New Value = Bad Cluster
DEC AX
MOV DX,OFFSET MARKMSG
JMP WRT_FAT
UNMARK: DEC AX
CMP BX,AX ; If Not Bad,
JE IS_BAD
MOV DX,OFFSET NOTBAD
ERROUT: MOV AH,9 ; Output Error Message
INT 21H
JMP STRIP
IS_BAD: MOV BX,CLUST ; Get Cluster Number
XOR AX,AX ; New Value = Good Cluster
MOV DX,OFFSET UNMRKMSG
WRT_FAT: PUSH DX
CALL SETCLST
PUSH SI ; Save Parameter Pointer
MOV AL,DRIVE ; Write FAT #1
MOV CX,FATSEC
MOV DX,1
MOV BX,OFFSET FATBUF
INT 26H
POPF
MOV AL,DRIVE ; Write FAT #2
MOV CX,FATSEC
MOV DX,CX
INC DX
MOV BX,OFFSET FATBUF
INT 26H
POPF
POP SI ; Restore Parameter Pointer
MOV AH,9 ; Output UnMarked Message
POP DX
INT 21H
JMP STRIP
NEXTCLST: CMP FATSIZE,3 ; If FAT Size = 16 Bits,
JE NEXT_12
SHL BX,1 ; Simply Read Next Cluster #
MOV BX,FATBUF[BX]
RET ; Done
NEXT_12: PUSH CX ; Save Registers
MOV CX,BX ; Word # = Cluster # * 1.5
SHL CX,1
ADD BX,CX
SHR BX,1
MOV BX,FATBUF[BX]
JNC NEXT_OK ; If Odd, Use 12 MSB's
MOV CL,4
SHR BX,CL
NEXT_OK: AND BX,0FFFH ; Else Use 12 LSB's
POP CX ; Restore Registers
RET ; Done
SETCLST: PUSH AX ; Save Registers
PUSH BX
CMP FATSIZE,3 ; If FAT Size = 16 Bits,
JE SETC_12
SHL BX,1 ; Simply Read Next Cluster #
MOV FATBUF[BX],AX
JMP SHORT SET_DONE ; Done
SETC_12: PUSH CX ; Save Registers
MOV CX,BX ; Word # = Cluster # * 1.5
SHL CX,1
ADD BX,CX
SHR BX,1
MOV CX,0F000H
JNC SETC_OK ; If Odd, Use 12 MSB's
MOV CL,4
SHL AX,CL
MOV CX,0FH
SETC_OK: AND FATBUF[BX],CX
OR FATBUF[BX],AX
POP CX
SET_DONE: POP BX
POP AX
RET ; Done
GET_WORD: PUSH BX ; Save Register
XOR DX,DX ; Value = 0
GET_WRD1: LODSB ; Read Character
CMP AL,'0' ; If Not Numeric, Done
JB GET_WRD2
CMP AL,'9'
JA GET_WRD2
SUB AL,'0' ; Convert to BCD
CBW
MOV BX,AX ; Value = Value*10+BCD
MOV AX,10
MUL DX
ADD AX,BX
MOV DX,AX
JMP GET_WRD1 ; Repeat
GET_WRD2: DEC SI
POP BX ; Restore Register
RET ; Done
STRIP0: CMP BYTE PTR [DI],'0' ; If Character != '0', Done
JNE STRIP1
CMP BYTE PTR [DI+1],'0' ; If Next Character != Digit,
JL STRIP1 ; Done
CMP BYTE PTR [DI+1],'9'
JG STRIP1
MOV BYTE PTR [DI],' ' ; Change '0' to ' '
INC DI ; Point to Next Character
JMP SHORT STRIP0 ; Repeat
STRIP1: RET ; Done
DEC2OUT: PUSH AX ; Save Registers
PUSH BX
XOR AH,AH ; Clear AH
MOV BL,10 ; AH=AX%10,AL=AX/10
DIV BL
ADD AX,'00' ; Convert to ASCII
SUB DI,2
MOV [DI],AX ; Store in String
POP BX ; Restore Registers
POP AX
RET ; Done
DEC4OUT: PUSH AX ; Save Registers
PUSH BX
MOV BL,100 ; AH=AX%100,AL=AX/100
DIV BL
XCHG AH,AL ; Convert 2 LSD's
CALL DEC2OUT
XCHG AH,AL ; Convert 2 MSD's
CALL DEC2OUT
POP BX ; Restore Registers
POP AX
RET ; Done
DEC5OUT: PUSH AX ; Save Registers
PUSH BX
PUSH DX ; DX=AX%10000,AX=AX/10000
MOV BX,10000
XOR DX,DX
DIV BX
XCHG DX,AX ; Convert 4 LSD's
CALL DEC4OUT
XCHG DX,AX ; Convert MSD
ADD AL,'0'
SUB DI,1
MOV [DI],AL
POP DX ; Restore Registers
POP BX
POP AX
RET ; Done
FATBUF LABEL WORD
CODE ENDS
END MARK